<template>
	<div :class="$style['device-transfer-drawer']">
		<div :class="$style['device-transfer-panel']">
			<!-- <h6>{{ titles[0] || '设备列表' }}</h6> -->
			<div :class="$style['device-transfer-filter']">
				<el-input v-model="optionalKeyword" size="small" placeholder="请输入搜索内容" :prefix-icon="Search" clearable
					@input="handleSearchOptionalList" />
			</div>

			<div :class="$style['device-list']">
				<el-checkbox v-model="checkAll" :indeterminate="isIndeterminate" @change="handleCheckAllChange">
					全选
				</el-checkbox>
				<el-scrollbar height="100%">
					<el-checkbox-group v-model="deviceChooseTempData">
						<template :key="item[keymap.value]" v-for="item in currentOptionalList">
							<el-checkbox :value="item[keymap.value]" :label="item[keymap.label]" />
						</template>
					</el-checkbox-group>
				</el-scrollbar>
			</div>

			<el-pagination :class="$style['device-paging']" small background layout="prev, pager, next"
				:total="currentPaging.total" :hide-on-single-page="false" v-model:current-page="currentPaging.page"
				v-model:page-size="currentPaging.limit" :pager-count="5" @current-change="handleCurrentChange"
				v-if="visiblePaging" />
		</div>

		<div :class="$style['device-transfer-transform']">
			<el-button type="primary" size="small" :disabled="deviceChooseTempData.length === 0"
				@click="handleTransferAppend">
				<el-icon>
					<DArrowRight />
				</el-icon>
			</el-button>

			<el-button type="primary" size="small" :disabled="resultChooseTempData.length === 0"
				@click="handleTransferRemove">
				<el-icon>
					<DArrowLeft />
				</el-icon>
			</el-button>
		</div>

		<div :class="$style['device-transfer-panel']">
			<!-- <h6>{{ titles[1] || '已选设备' }}</h6> -->
			<div :class="$style['device-transfer-filter']">
				<el-input v-model="resultKeyword" size="small" placeholder="请输入搜索内容" :prefix-icon="Search" clearable
					@input="handleSearchResultList" />
			</div>
			<div :class="$style['device-list']">
				<el-checkbox v-model="chooseAll" :indeterminate="isChooseIndeterminate" @change="handleChooseAllChange">
					全选
				</el-checkbox>
				<el-scrollbar height="100%">
					<el-checkbox-group v-model="resultChooseTempData">
						<template :key="item[keymap.value]" v-for="item in currentResultList">
							<el-checkbox :value="item[keymap.value]" :label="item[keymap.label]" />
						</template>
					</el-checkbox-group>
				</el-scrollbar>
			</div>
		</div>
	</div>
</template>

<script>
import { ref, reactive, watch } from 'vue'
import { Calendar, Search, DArrowLeft, DArrowRight } from '@element-plus/icons-vue'
import VueTypes from 'vue-types'

export default {
	name: 'device-transfer',
	components: {
		Search,
		DArrowLeft,
		DArrowRight
	},
	/**
	 * 传入数据
	 * @property {String}  value           选中项绑定值
	 * @property {String}  data            Transfer 的数据源
	 * @property {Array}  titles          自定义列表标题 [左侧列表标题,右侧列表镖旗]
	 * @property {Boolean}  filterable     是否可搜索
	 */
	props: {
		keymap: VueTypes.shape({
			value: String,
			label: String
		}).def({
			value: 'value',
			label: 'label'
		}),
		value: VueTypes.array.def([]),
		data: VueTypes.array.def([]),
		titles: VueTypes.array.def([]),
		filterable: VueTypes.bool.def(false)
	},
	emits: ['update:value'],
	setup(props, { emit }) {
		const optionalKeyword = ref('')
		const resultKeyword = ref('')
		const currentOptionalList = ref(props.data)
		const currentResultList = ref([])
		const deviceChooseTempData = ref([])
		const resultChooseTempData = ref([])
		const visiblePaging = ref(true)
		const currentPaging = reactive({
			page: 1,
			limit: 30,
			total: props.data.length
		})

		let optionalList = props.data
		let pagingList = []
		let resultList = []
		let resultData = props.value
		let resultMap = {}

		const formatResultMap = () => {
			resultMap = resultData.reduce((map, val) => {
				map[val] = true

				return map
			}, {})

			// 重置左右侧的待输出列表
			pagingList = []
			resultList = []

			optionalList.map(item => {
				if (resultMap[item[props.keymap.value]]) {
					resultList.push(item)
				} else {
					pagingList.push(item)
				}
			})

			currentResultList.value = resultList
			currentPaging.total = pagingList.length

			getVisibleOptionalList()
		}

		const handleSearchOptionalList = () => {
			if (optionalKeyword.value.trim()) {
				const reg = new RegExp(optionalKeyword.value.trim(), 'i')

				visiblePaging.value = false
				currentOptionalList.value = pagingList.filter(item => reg.test(item[props.keymap.label]))
			} else {
				visiblePaging.value = true
				getVisibleOptionalList()
			}
		}

		const handleSearchResultList = () => {
			if (resultKeyword.value.trim()) {
				const reg = new RegExp(resultKeyword.value.trim(), 'i')

				currentResultList.value = resultList.filter(item => reg.test(item[props.keymap.label]))
			} else {
				formatResultMap()
			}
		}

		// 更新页码
		const handleCurrentChange = val => {
			currentPaging.page = val
			getVisibleOptionalList()
		}

		const getVisibleOptionalList = () => {
			currentOptionalList.value = pagingList.slice((currentPaging.page - 1) * currentPaging.limit, currentPaging.page * currentPaging.limit)
		}

		// 重置展示列表
		const resetList = () => {
			optionalKeyword.value = ''
			visiblePaging.value = true

			formatResultMap()
		}

		// 添加到结果列表
		const handleTransferAppend = () => {
			resultData.push(...deviceChooseTempData.value)

			resetList()

			deviceChooseTempData.value = []

			emit('update:value', currentResultList.value.map(item => item[props.keymap.value]))
		}

		// 移除结果列表中的选项
		const handleTransferRemove = () => {
			const tempRemoveMap = resultChooseTempData.value.reduce((map, val) => {
				map[val] = true

				return map
			}, {})

			resultData = resultData.filter(val => !tempRemoveMap[val])

			resetList()

			resultChooseTempData.value = []

			emit('update:value', currentResultList.value.map(item => item[props.keymap.value]))
		}

		watch(
			() => props.data,
			(data) => {
				optionalList = data
				currentPaging.page = 1

				formatResultMap()
			}
		)

		watch(
			() => props.value,
			(value) => {
				resultData = value
				currentPaging.page = 1

				formatResultMap()
			}
		)

		formatResultMap()

		const checkAll = ref(false)
		const isIndeterminate = ref(true)
		const handleCheckAllChange = (val) => {
			deviceChooseTempData.value = val ? currentOptionalList.value.map(item => item.id) : []
			isIndeterminate.value = false
		}

		const chooseAll = ref(false)
		const isChooseIndeterminate = ref(true)
		const handleChooseAllChange = (val) => {
			resultChooseTempData.value = val ? currentResultList.value.map(item => item.id) : []
			isChooseIndeterminate.value = false
		}
		return {
			Search,
			optionalKeyword,
			resultKeyword,
			visiblePaging,
			currentPaging,
			currentOptionalList,
			currentResultList,
			deviceChooseTempData,
			resultChooseTempData,
			handleSearchOptionalList,
			handleSearchResultList,
			handleCurrentChange,
			handleTransferAppend,
			handleTransferRemove,
			handleCheckAllChange,
			checkAll,
			isIndeterminate,
			handleChooseAllChange,
			isChooseIndeterminate,
			chooseAll
		}
	}
}
</script>

<style lang="scss" module>
.device-transfer-drawer {
	box-sizing: border-box;
	overflow: hidden;
	display: flex;
	justify-content: space-between;
	gap: 18px;
	width: 100%;
	height: calc(100% - 70px);
	padding: 12px 0;
	border-top: 1px solid #EDEFF1;
	border-bottom: 1px solid #EDEFF1;
}


.device-transfer-panel {
	flex: 1 0 0;
	display: flex;
	flex-direction: column;
	gap: 10px;
	height: 100%;
	width: 40%;
	overflow: hidden;

	& [class~="el-checkbox"] {
		display: flex;
	}
}

.device-transfer-transform {
	display: flex;
	flex-direction: column;
	justify-content: center;
	gap: 24px;
	width: 20%;
	padding: 0 24px;

	& [class~="el-button"] {
		margin: 0;
	}
}

.device-list {
	flex: 1 0 0;
	height: 0;
}

.device-paging {
	justify-content: center;
	margin-top: 25px;
}

.device-transfer-result {
	display: flex;
	flex-wrap: wrap;
	gap: 12px;
}
</style>
